﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FinalProject.Services.Interfaces;
using FinalProject.Data.EntityRepositories.Interfaces;
using FinalProject.Data.DBInteractions.Interfaces;
using FinalProject.Data.Search;
using FinalProject.Entities;

namespace FinalProject.Services.Services
{
    public class UserService : IUserService
    {
        private readonly IUserRepository _repository;
        private readonly IUserRoleRepository _userRoleRepository;
        private readonly IUserDetailsRepository _userDetailsRepository;
        private readonly IUnitOfWork _unitOfWork;
        public UserService(IUserRepository repository, IUnitOfWork unitOfWork, IUserRoleRepository userRoleRepository, IUserDetailsRepository userDetailsRepository)
        {
            this._repository = repository;
            this._unitOfWork = unitOfWork;
            this._userRoleRepository = userRoleRepository;
            this._userDetailsRepository = userDetailsRepository;
        }

        #region Members

        public PagedListResult<User> GetAll()
        {
            var entities = _repository.Search(new SearchQuery<User>());
            return entities;
        }

        public Entities.User GetById(int id)
        {
            var entity = _repository.GetById(id);
            return entity;
        }

        public void Create(Entities.User entity)
        {
            if (entity.UserRoles != null && entity.UserRoles.Any())
            {
                foreach (var role in entity.UserRoles)
                    _userRoleRepository.Attach(role);
            }
            _repository.Add(entity);
            _unitOfWork.Commit();
        }

        public void Update(Entities.User entity)
        {
            _repository.Update(entity);
            _unitOfWork.Commit();
        }

        public void Delete(int id)
        {
            var entity = _repository.GetById(id);
            _repository.Delete(entity);
            _unitOfWork.Commit();
        }

        public void Save()
        {
            _unitOfWork.Commit();
        }

        #endregion



        public Entities.User GetByName(string name)
        {
            var entity = _repository.Get(x => x.UserName == name);
            return entity;
        }


        public Entities.User GetUserWithRoles(int id)
        {
            var query = new SearchQuery<User>();
            query.IncludeProperties = "UserRoles";
            query.AddFilter(x => x.Id == id);
            var entity = _repository.Search(query);
            return entity.Entities.FirstOrDefault();
        }

        public Entities.User GetUserWithRoles(string name)
        {
            var query = new SearchQuery<User>();
            query.IncludeProperties = "UserRoles";
            query.AddFilter(x => x.UserName == name);
            var entity = _repository.Search(query);
            return entity.Entities.FirstOrDefault();
        }


        public User GetUserWithRolesAndUserDetails(int id)
        {
            var query = new SearchQuery<User>();
            query.IncludeProperties = "UserRoles";
            query.IncludeProperties = "UserDetails";
            query.AddFilter(x => x.Id == id);
            var entity = _repository.Search(query);
            return entity.Entities.FirstOrDefault();
        }

        public void Update(User entity, ICollection<UserRole> userRoles)
        {
            _repository.Update(entity);
            _repository.LoadNavigationCollection(entity, u => u.UserRoles);
            entity.UserRoles.Clear();
            entity.UserRoles = userRoles;
            _unitOfWork.Commit();
        }
    }
}
